package com.wust.service.impl;

import com.wust.common.ServerResponse;
import com.wust.dao.*;
import com.wust.entity.*;
import com.wust.service.IStatisticsService;
import com.wust.vo.BMIVo;
import com.wust.vo.HeartRateVo;
import com.wust.vo.HeartWeek;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.security.auth.callback.CallbackHandler;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by lenovo on 2018/6/13.
 */
@Service("iStatisticsService")
public class StatisticsServiceImpl implements IStatisticsService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private SuggestionMapper suggestionMapper;

    @Autowired
    private BMIStatisticsMapper bmiStatisticsMapper;

    @Autowired
    private CheckupRecordMapper checkupRecordMapper;

    @Autowired
    private HrStatisticsMapper hrStatisticsMapper;

    @Autowired
    private DayCountMapper dayCountMapperd;

    //身高和体重是可以修改的
    //获取当前最新的
    public ServerResponse<BMIVo> getUserCurrentBMI(int userId){
        BMIStatistics bmiStatistics  = bmiStatisticsMapper.selectLatestOneByUserId(userId);
        User user = userMapper.selectByPrimaryKey(userId);
        double weight = user.getWeight();//KG
        double height = user.getHeight();//cm
        double value = weight/(height*height*0.01*0.01);
        //数据未被更新，直接返回已有的历史数据
        if(bmiStatistics != null && bmiStatistics.getValue().equals(value)){
            BMIVo bmiVo = assembleBMIVo(height,weight,bmiStatistics);
            return ServerResponse.createBySuccessMessageAndData("获取BMI成功",bmiVo);
        }
        //数据需要更新或没有数据，保留以前的历史数据，直接插入新的数据，再返回
        BMIStatistics bmiStatistics1 = new BMIStatistics();
        bmiStatistics1.setUserId(userId);
        bmiStatistics1.setValue(value);
        /*
        体重过低	<18.5
        体重正常	18.5-23.9
        超重	24-27.9
        肥胖	≥28
        */
        if(value < 18.5){
            bmiStatistics1.setStatusId(1);
        }else if(value <= 23.9){
            bmiStatistics1.setStatusId(2);
        }else if(value <= 27.9){
            bmiStatistics1.setStatusId(3);
        }else {
            bmiStatistics1.setStatusId(4);
        }
        int resultCount = bmiStatisticsMapper.insertSelective(bmiStatistics1);
        if(resultCount > 0){
            BMIVo bmiVo = assembleBMIVo(height,weight,bmiStatistics1);
            return ServerResponse.createBySuccessMessageAndData("获取BMI成功",bmiVo);
        }
        return ServerResponse.createByErrorMessage("获取失败");
    }

    public BMIVo assembleBMIVo(double height, double weight, BMIStatistics bmiStatistics){
        BMIVo bmiVo = new BMIVo();
        bmiVo.setUserId(bmiStatistics.getUserId());
        bmiVo.setStatus(bmiStatistics.getStatusId());
        DecimalFormat df   = new DecimalFormat("######0.00");
        bmiVo.setBMIvalue(Double.parseDouble(df.format(bmiStatistics.getValue())));
        bmiVo.setHeight(height);
        bmiVo.setWeight(weight);
        bmiVo.setSuggestion(suggestionMapper.selectRamdomOneByStatus(bmiStatistics.getStatusId()).getSuggestion());
        return bmiVo;
    }

    //获得时间段
    //获得某时间段的数据（去除掉不符合条件的）
    //求平均值（每天的）和方差（一次的）
    public ServerResponse<HeartRateVo> getOneHeartStatistics(int userId){
        //保留两位小数（会四舍五入）
        DecimalFormat df   = new DecimalFormat("######0.00");
        HrStatistics hrStatistics = new HrStatistics();
        hrStatistics.setUserId(userId);

        CheckupRecord checkupRecord = checkupRecordMapper.selectLatestInValidByUserId(userId);
        hrStatistics.setEndTime(checkupRecord.getCreateTime());

        checkupRecord = checkupRecordMapper.selectLatestInValidByUserIdAndTime(userId,checkupRecord.getCreateTime());
        hrStatistics.setBeginTime(checkupRecord.getCreateTime());
        //若是两条相同的记录，则不重复插入，直接获取
        HrStatistics hrStatistics1 = hrStatisticsMapper.selectLatestByUserId(userId);
        if(hrStatistics1 != null && hrStatistics1.getBeginTime().equals(hrStatistics.getBeginTime())
                && hrStatistics1.getEndTime().equals(hrStatistics.getEndTime())){
            HrStatistics oldHrStatistics = hrStatisticsMapper.selectSecondByUserIdAndTime(userId,hrStatistics1.getCreateTime());
            HeartRateVo heartRateVo = assembleHeartRateVo(hrStatistics1,oldHrStatistics);
            System.out.println(oldHrStatistics);
            return ServerResponse.createBySuccessMessageAndData("获取本次车程心率统计值成功",heartRateVo);
        }

        double hour = ((hrStatistics.getEndTime().getTime()-hrStatistics.getBeginTime().getTime())*0.1)/(100* 60 * 60);
        hrStatistics.setHour(Double.valueOf(df.format(hour)));
//        获得这个时间段的所有数据（去除掉不符合条件的）
        List<CheckupRecord> checkupRecords = checkupRecordMapper.selectAllBetweenTime(userId,hrStatistics.getBeginTime(),hrStatistics.getEndTime());
        if(checkupRecords.size()<30){
            return ServerResponse.createByErrorMessage("开车时间过短，数据太少，无法分析");
        }
        //计算全部的平均值和方差，再选出30个数返回以展示
        ArrayList<Double> arrayList = new ArrayList<>();
        int num =(int) checkupRecords.size()/30;
        int i,j=0;
        double allsum=0;
        String value="";
        for(i=0;i<checkupRecords.size();i++)
        {
            allsum +=checkupRecords.get(i).getHeartRate();
            if(checkupRecords.get(i).getHeartRate()>60.0&&checkupRecords.get(i).getHeartRate()<100.0){
                j++;
            }
            arrayList.add((double)checkupRecords.get(i).getHeartRate());
        }
        for(i=0;i<30;i+=num){
            value = value+Double.toString(checkupRecords.get(i).getHeartRate())+"/";
        }
        double rate = (j*0.1/checkupRecords.size())*1000;

        hrStatistics.setQualifiedRate((int)rate);
        double var = Double.parseDouble(df.format(Variance(arrayList)));//方差
        double ave = (int)allsum/checkupRecords.size();//平均值
        hrStatistics.setVariance(var);
        hrStatistics.setAverage(ave);
        hrStatistics.setHeartRateValue(value);
        if(var<20){
            hrStatistics.setStatusId(6);
        }
        else if(var<=50){
            hrStatistics.setStatusId(7);
        }else {
            hrStatistics.setStatusId(5);
        }

        int resultCount = hrStatisticsMapper.insertSelective(hrStatistics);
        if(resultCount > 0){
            HeartRateVo heartRateVo = assembleHeartRateVo(hrStatistics,hrStatistics1);
            return ServerResponse.createBySuccessMessageAndData("获取本次车程心率统计值成功",heartRateVo);
        }
        return ServerResponse.createByErrorMessage("获取本次车程心率统计值失败");
    }

    public static double Variance(ArrayList<Double> x) {
        int m=x.size();
        double sum=0;
        for(int i=0;i<m;i++){//求和
            sum+=x.get(i);
        }
        double dAve=sum/m;//求平均值
        double dVar=0;
        for(int i=0;i<m;i++){//求方差
            dVar+=(x.get(i)-dAve)*(x.get(i)-dAve);
        }
        return dVar/m;
    }

    public HeartRateVo assembleHeartRateVo(HrStatistics hrStatistics,HrStatistics oldHrHrStatistics){
        HeartRateVo heartRateVo = new HeartRateVo();
        heartRateVo.setHeartRateValue(hrStatistics.getHeartRateValue());
        heartRateVo.setHour(hrStatistics.getHour());
        heartRateVo.setUserId(hrStatistics.getUserId());
        heartRateVo.setEndTime(hrStatistics.getEndTime());
        heartRateVo.setBeginTime(hrStatistics.getBeginTime());
        heartRateVo.setVariance(hrStatistics.getVariance());
        heartRateVo.setAverage(hrStatistics.getAverage().intValue());
        heartRateVo.setStatusId(hrStatistics.getStatusId());
        heartRateVo.setSuggestion(suggestionMapper.selectRamdomOneByStatus(hrStatistics.getStatusId()).getSuggestion());
        heartRateVo.setArate(hrStatistics.getQualifiedRate());
        if(hrStatistics.getAverage()>oldHrHrStatistics.getAverage()){
            heartRateVo.setAtrend(2);
        }else if(hrStatistics.getAverage()==oldHrHrStatistics.getAverage()){
            heartRateVo.setAtrend(1);
        }else {
            heartRateVo.setAtrend(0);
        }
        if(hrStatistics.getVariance()>oldHrHrStatistics.getVariance()){
            heartRateVo.setVtrend(2);
        }else if(hrStatistics.getVariance()==oldHrHrStatistics.getVariance()){
            heartRateVo.setVtrend(1);
        }else {
            heartRateVo.setVtrend(0);
        }
        return heartRateVo;
    }

    @Override
    public ServerResponse<HeartWeek> getWeekHeartStatistics(int userId) {
        //七个值（一周每天一个值）包括今天在内的7天
        //忽略掉0与255

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
        Date nowDate = new Date();
        Date beginDate = new Date();
        Date endDate;
        Calendar date = Calendar.getInstance();

        HeartWeek heartWeek = new HeartWeek();
        heartWeek.setUserId(userId);
        Map<Integer,Integer> values = new HashMap<>();

        for(int i=0;i<7;i++)
        {
            endDate = beginDate;
            date.setTime(nowDate);
            date.set(Calendar.DATE, date.get(Calendar.DATE) - i);//0对应2018-06-15 00:00:00
            try {
                beginDate = dft.parse(dft.format(date.getTime()));
                beginDate = df.parse(df.format(beginDate));
            } catch (ParseException e) {
                e.printStackTrace();
                return ServerResponse.createByErrorMessage("获取失败");
            }
            DayCount dayCount1 = dayCountMapperd.selectByUserIdAndBeginTimeAndEndTime(userId,beginDate,endDate);
            if(dayCount1 == null){
                List<CheckupRecord> checkupRecords = checkupRecordMapper.selectAllBetweenTime(userId,beginDate,endDate);
                int aver;
                if(checkupRecords.size()==0){
                    aver =0;
                }else {
                    int sum =0;
                    for(int j=0;j<checkupRecords.size();j++){
                        sum += checkupRecords.get(j).getHeartRate();
                    }
                    aver = sum/checkupRecords.size();
                }
                DayCount dayCount = new DayCount();
                dayCount.setUserId(userId);
                dayCount.setBeginTime(beginDate);
                dayCount.setEndTime(endDate);
                dayCount.setAverage(aver);
                int resultCount = dayCountMapperd.insertSelective(dayCount);
                if(resultCount <= 0){
                    return ServerResponse.createByErrorMessage("获取失败");
                }
                date.setTime(beginDate);
                int day = date.get(Calendar.DATE);
                values.put(day,aver);
            }else {
                date.setTime(beginDate);
                int day = date.get(Calendar.DATE);
                values.put(day,dayCount1.getAverage());
            }
        }
        heartWeek.setValues(values);
        return  ServerResponse.createBySuccessMessageAndData("获取近七天数据成功",heartWeek);
    }

//    public static void main(String[] args) {
//        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
//        Date beginDate = new Date();
//        Date endDate = new Date();
//        Calendar date = Calendar.getInstance();
//        date.setTime(beginDate);
//        date.set(Calendar.DATE, date.get(Calendar.DATE) - 0);//0对应2018-06-15 00:00:00
//        try {
//            beginDate = dft.parse(dft.format(date.getTime()));
//            beginDate = df.parse(df.format(beginDate));
////            System.out.println(beginDate);
////            System.out.println(endDate);
//        } catch (ParseException e) {
//            e.printStackTrace();
//        }
//
//
//
//    }

}
